package lab3;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 版本2.0 习题集系统类
 * 提供生成大量习题和格式化显示的功能，包含Main入口
 */
public class ExerciseSetSystem {
    private List<Exercise> exercises;  // 习题列表
    private Random random;             // 随机数生成器

    /**
     * 构造函数
     */
    public ExerciseSetSystem() {
        this.exercises = new ArrayList<>();
        this.random = new Random();
    }

    /**
     * 生成指定数量的加法习题
     * @param count 习题数量
     * @param maxValue 操作数的最大值（包含）
     */
    public void generateAdditionExercises(int count, int maxValue) {
        for (int i = 0; i < count; i++) {
            double operand1 = random.nextInt(maxValue + 1);
            double operand2 = random.nextInt(maxValue + 1);
            AbstractArithmeticExpression expr = new AdditionExpression(operand1, operand2);
            // 直接使用AbstractArithmeticExpression构造Exercise
            Exercise exercise = new Exercise(expr);
            exercises.add(exercise);
        }
    }

    /**
     * 生成指定数量的减法习题
     * 确保结果为非负数
     * @param count 习题数量
     * @param maxValue 操作数的最大值（包含）
     */
    public void generateSubtractionExercises(int count, int maxValue) {
        for (int i = 0; i < count; i++) {
            // 确保第一个操作数大于等于第二个操作数，使结果非负
            double operand2 = random.nextInt(maxValue + 1);
            double operand1 = operand2 + random.nextInt(maxValue + 1);
            AbstractArithmeticExpression expr = new SubtractionExpression(operand1, operand2);
            // 直接使用AbstractArithmeticExpression构造Exercise
            Exercise exercise = new Exercise(expr);
            exercises.add(exercise);
        }
    }

    /**
     * 生成指定数量的混合习题（加法和减法）
     * @param count 习题数量
     * @param maxValue 操作数的最大值（包含）
     */
    public void generateMixedExercises(int count, int maxValue) {
        for (int i = 0; i < count; i++) {
            if (random.nextBoolean()) {
                // 生成加法习题
                generateAdditionExercises(1, maxValue);
            } else {
                // 生成减法习题
                generateSubtractionExercises(1, maxValue);
            }
        }
    }

    /**
     * 格式化显示所有习题
     * @param exercisesPerLine 每行显示的习题数量
     * @param showAnswers 是否显示答案
     */
    public void displayExercises(int exercisesPerLine, boolean showAnswers) {
        System.out.println("\n===== 习题集 =====");
        System.out.println("总题数: " + exercises.size());
        System.out.println();

        for (int i = 0; i < exercises.size(); i++) {
            Exercise exercise = exercises.get(i);
            String exprStr;
            
            // 检查表达式类型并构建相应的字符串
            if (exercise.getExpression() != null) {
                // 处理版本1.0的表达式
                if (showAnswers) {
                    exprStr = String.format("%.2f %c %.2f = %.2f",
                            exercise.getExpression().getOperand1(),
                            exercise.getExpression().getOperator(),
                            exercise.getExpression().getOperand2(),
                            exercise.getExpression().getResult());
                } else {
                    exprStr = String.format("(%.2f %c %.2f)",
                            exercise.getExpression().getOperand1(),
                            exercise.getExpression().getOperator(),
                            exercise.getExpression().getOperand2());
                }
            } else if (exercise.getAbstractExpression() != null) {
                // 处理版本2.0的抽象表达式
                AbstractArithmeticExpression abstractExpr = exercise.getAbstractExpression();
                if (showAnswers) {
                    exprStr = String.format("%.2f %c %.2f = %.2f",
                            abstractExpr.getOperand1(),
                            abstractExpr.getOperatorSymbol(),
                            abstractExpr.getOperand2(),
                            abstractExpr.calculate());
                } else {
                    exprStr = String.format("(%.2f %c %.2f)",
                            abstractExpr.getOperand1(),
                            abstractExpr.getOperatorSymbol(),
                            abstractExpr.getOperand2());
                }
            } else {
                exprStr = "(无效表达式)";
            }
            
            // 格式化输出，包含序号
            System.out.printf("%2d. %-20s", (i + 1), exprStr);
            
            // 控制每行显示的习题数量
            if ((i + 1) % exercisesPerLine == 0) {
                System.out.println();
            }
        }
        
        // 确保最后一行换行
        if (exercises.size() % exercisesPerLine != 0) {
            System.out.println();
        }
        
        System.out.println("\n==================\n");
    }

    /**
     * 获取习题列表
     * @return 习题列表
     */
    public List<Exercise> getExercises() {
        return new ArrayList<>(exercises);  // 返回副本以保护封装
    }

    /**
     * 清空习题列表
     */
    public void clearExercises() {
        exercises.clear();
    }

    /**
     * 主方法
     */
    public static void main(String[] args) {
        ExerciseSetSystem system = new ExerciseSetSystem();
        
        // 生成50道加法习题
        system.generateAdditionExercises(50, 100);
        System.out.println("已生成50道加法习题");
        
        // 显示部分加法习题作为示例
        System.out.println("\n加法习题示例:");
        List<Exercise> additionExercises = system.getExercises().subList(0, 5);
        for (int i = 0; i < additionExercises.size(); i++) {
            Exercise ex = additionExercises.get(i);
            if (ex.getAbstractExpression() != null) {
                AbstractArithmeticExpression abstractExpr = ex.getAbstractExpression();
                System.out.printf("%d. %.2f %c %.2f\n", 
                        (i + 1), abstractExpr.getOperand1(), 
                        abstractExpr.getOperatorSymbol(), abstractExpr.getOperand2());
            }
        }
        
        // 清空习题列表
        system.clearExercises();
        
        // 生成50道减法习题
        system.generateSubtractionExercises(50, 100);
        System.out.println("\n已生成50道减法习题");
        
        // 显示部分减法习题作为示例
        System.out.println("\n减法习题示例:");
        List<Exercise> subtractionExercises = system.getExercises().subList(0, 5);
        for (int i = 0; i < subtractionExercises.size(); i++) {
            Exercise ex = subtractionExercises.get(i);
            if (ex.getAbstractExpression() != null) {
                AbstractArithmeticExpression abstractExpr = ex.getAbstractExpression();
                System.out.printf("%d. %.2f %c %.2f\n", 
                        (i + 1), abstractExpr.getOperand1(), 
                        abstractExpr.getOperatorSymbol(), abstractExpr.getOperand2());
            }
        }
        
        // 清空习题列表
        system.clearExercises();
        
        // 生成50道混合习题
        system.generateMixedExercises(50, 100);
        System.out.println("\n已生成50道混合习题");
        
        // 格式化显示混合习题（不显示答案）
        system.displayExercises(3, false);
        
        // 运行单元测试（可选）
        // runUnitTests();
    }

    /**
     * 运行所有单元测试
     */
    private static void runUnitTests() {
        System.out.println("\n===== 运行单元测试 =====");
        
        try {
            // 使用JUnitCore运行测试类
            System.out.println("\n请使用JUnit测试运行器执行测试类");
            System.out.println("可通过IDE的JUnit运行功能或使用JUnitTestRunner类运行测试");
        } catch (Exception e) {
            System.out.println("测试运行出错: " + e.getMessage());
        }
        
        System.out.println("\n===== 测试信息显示完成 =====");
    }
}